package org.example.websocket;

import org.example.models.Server;
import org.example.server.JSONRead;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
@Configuration
@Order(value = 1)
public class SocketInterceptor implements CommandLineRunner {
    public static int id;   //代理服务器唯一指定id，由主服务器生成并返回

    @Autowired
    private SocketProperties properties;

    @Override
    public void run(String ...args) throws Exception {
        ServerSocket server = null;
        Socket socket = null;
        server = new ServerSocket(properties.getPort());
        System.out.println("设备服务器已经开启,监听端口: " + properties.getPort());
        ThreadPoolExecutor pool = new ThreadPoolExecutor(
                properties.getPoolCore(),
                properties.getPoolMax(),
                properties.getPoolKeep(),
                TimeUnit.SECONDS,   //时间单位
                new ArrayBlockingQueue<Runnable>(properties.getPoolQueueInit()),    //线程等待队列
                new ThreadPoolExecutor.DiscardPolicy()  //拒绝策略
        );
        //使用DiscardPolicy策略时注意，如果设置的core, max, keep过小，可能会出现无限阻塞的风险
        sendSelfIPv4(); //发送自身IP给主服务器

        while(true) {
            socket = server.accept();   //监听接口信息
            //分布式服务器维护一个在线用户表，每个分布式服务器最多维护200个线程，也就是说最多一个分布式服务器维护200个在线用户
            pool.execute(new SocketConfig(socket)); //将该信息放入线程池中运行
        }
    }

    private void sendSelfIPv4() {
        try {
            Socket sendServerSocket = new Socket(Server.getMainServerIP(), Server.getMainServerPort());
            String json =
                    "{\n" +
                    "   \"type\": \"server\",\n" +
                    "   \"data\": {\n" +
                    "       \"operation\": \"set\",\n" +
                    "       \"ipv4\": \"" + Server.getProxyServerIP() + "\",\n" +
                    "       \"port\": \"" + Server.getProxyServerPort() + "\"\n" +
                    "   }\n" +
                    "}";
            PrintWriter pw = new PrintWriter(sendServerSocket.getOutputStream());
            pw.write(json);
            pw.flush();

            InputStream is = sendServerSocket.getInputStream();
            byte[] bytes = new byte[8 * 6];
            is.read(bytes);
            String message = (new String(bytes)).trim();
            if (message.equals("1")) {
                throw new IOException();
            } else {
                id = Integer.valueOf(message);
            }

            is.close();
            pw.close();
            sendServerSocket.close();
        } catch (UnknownHostException e) {
            System.out.println("主服务器未响应！请重新测试");
            System.exit(-1);
        } catch (IOException e) {
            System.out.println("发送失败，可能是网络连接问题！");
            System.exit(-1);
        }
    }
}